
 /* Include Files ------------------------------------------------------------------------------- */
#include "stm32f10x.h"
#include "system_timer.h"
#include "iflash.h"
#include "uthread.h"

/* Macro Defines ------------------------------------------------------------------------------- */

/* Private variables --------------------------------------------------------------------------- */


/* Global Function Prototypes ------------------------------------------------------------------*/
uint32_t Ifm_iapupdtaeenable(void);


/* Global Function Prototypes ------------------------------------------------------------------ */
uint32_t Ifm_eraseInternal_Flash(uint32_t page_address, uint32_t page_number);
uint32_t Ifm_writeInternal_Flash(uint32_t flash_address, uint32_t *data, uint32_t length);
uint32_t Ifm_eraseBackMemory(void);
uint32_t Ifm_writeBackMemoryPage(uint32_t page_offset, uint8_t* buf);

/**
  * @brief  Ifm_eraseAppMemory.
  * @param  None
  * @retval None
  */
uint32_t Ifm_eraseAppMemory(void)
{
	uint32_t result = 0x00;
	
    result = Ifm_eraseInternal_Flash(APP_START_ADDRESS, APP_TOTAL_PAGE_NUMBER);
	return result;
}

/**
  * @brief  Ifm_eraseBackMemory.
  * @param  None
  * @retval None
  */
uint32_t Ifm_eraseBackMemory(void)
{
	uint32_t result = 0x00;
	
    result = Ifm_eraseInternal_Flash(BACK_START_ADDRESS, BACK_TOTAL_PAGE_NUMBER);
	return result;
}

/**
  * @brief  Ifm_writeAppMemoryPage.
  * @param  None
  * @retval None
  */
uint32_t Ifm_writeAppMemoryPage(uint32_t page_offset, uint8_t* buf)
{
	uint32_t page_address = 0;
	uint32_t result = 0x00;
	
	page_address = APP_START_ADDRESS + page_offset*IFLASH_PAGE_SIZE;
    result = Ifm_writeInternal_Flash(page_address, (uint32_t*)buf, IFLASH_PAGE_SIZE>>2);
	
	return result;
}

/**
  * @brief  Ifm_eraseBackMemory.
  * @param  None
  * @retval None
  */
uint32_t Ifm_writeBackMemoryPage(uint32_t page_offset, uint8_t* buf)
{
	uint32_t page_address = 0;
	uint32_t result = 0x00;
	
	page_address = BACK_START_ADDRESS + page_offset*IFLASH_PAGE_SIZE;
    result = Ifm_writeInternal_Flash(page_address, (uint32_t*)buf, IFLASH_PAGE_SIZE>>2);
	
	return result;
}

/**
  * @brief  Ifm_eraseInternal_Flash.
  * @param  None
  * @retval None
  */
uint32_t Ifm_eraseInternal_Flash(uint32_t page_address, uint32_t page_number)
{
    uint32_t page_counter = 0;
    uint32_t page_end_address = 0;
    FLASH_Status flash_status = FLASH_COMPLETE;
    
    //page_end_address = page_address + 1024*page_number - 1;
	page_end_address = page_address + 1024*page_number;
    if(page_end_address > (0X08000000+1024*128-1) ){  
        return (0x00);
    }
    FLASH_UnlockBank1();                                    
    
    for(page_counter = 0; (page_counter < page_number)&&(flash_status == FLASH_COMPLETE); page_counter++){
        flash_status = FLASH_ErasePage(page_address + page_counter*1024);   
    }
    if(flash_status !=  FLASH_COMPLETE){
        return (0x00);   
    }
    
    FLASH_LockBank1();
    
}

/**
  * @brief  Main program.
  * @param  None
  * @retval None
  */
uint32_t Ifm_writeInternal_Flash(uint32_t flash_address, uint32_t *data, uint32_t length)
{
    uint32_t write_counter = 0;
    uint32_t write_end_address = 0;
    FLASH_Status flash_status = FLASH_COMPLETE;
	
    write_end_address = flash_address + (length << 2) - 1;
    if(write_end_address >(0X08000000+1024*128-1) ){		
        return (0x00);
    }
    
    FLASH_UnlockBank1();  
    
    for(write_counter = 0; (write_counter < length)&&(flash_status == FLASH_COMPLETE); write_counter++){
        flash_status = FLASH_ProgramWord(flash_address, *(data+write_counter));
        flash_address = flash_address + 4;
    }
    if(flash_status !=  FLASH_COMPLETE){
        return (0x00);   
    }
    
    FLASH_LockBank1();
}


/**
  * @brief  Ifm_raadBackMemoryPage
  * @param  None
  * @retval None
  */
uint32_t Ifm_raadBackMemoryPage(uint32_t _ulFlashAddr, uint8_t *_ucpDst, uint32_t _ulSize)
{
	uint32_t i;

	if (_ulFlashAddr + _ulSize > (0x08000000 + 128*1024))
	{
		return 0;
	}

	if (_ulSize == 0)
	{
		return 0;
	}

	for (i = 0; i < _ulSize; i++)
	{
		*_ucpDst++ = *(uint8_t *)_ulFlashAddr++;
	}

	return 1;
}

